package com.hibase.core.lock.config;

import com.hibase.core.lock.aop.LockAnnotationAdvisor;
import com.hibase.core.lock.aop.LockInterceptor;
import com.hibase.core.lock.compoent.*;
import com.hibase.core.lock.executor.LockExecutor;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;

import java.util.List;

/**
 * 分布式锁自动配置器
 *
 * @author chenfeng
 * @version 1.0
 * @date 2021/10/22 13:22
 * @des https://gitee.com/cheershi
 */
@Configuration
@EnableConfigurationProperties(LockProperties.class)
@RequiredArgsConstructor
public class LockAutoConfiguration {

    private final LockProperties properties;

    /**
     * 注入LockTemplate
     * @param executors
     * @return
     */
    @SuppressWarnings("rawtypes")
    @Bean
    @ConditionalOnMissingBean
    public LockTemplate lockTemplate(List<LockExecutor> executors) {
        LockTemplate lockTemplate = new LockTemplate();
        lockTemplate.setProperties(properties);
        lockTemplate.setExecutors(executors);
        return lockTemplate;
    }

    /**
     * 注入key解析器
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public LockKeyBuilder lockKeyBuilder() {
        return new DefaultLockKeyBuilder();
    }

    /**
     * 失败策略
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public LockFailureStrategy lockFailureStrategy() {
        return new DefaultLockFailureStrategy();
    }

    /**
     * 分布式锁aop处理器
     * @param lockTemplate
     * @param lockKeyBuilder
     * @param lockFailureStrategy
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public LockInterceptor lockInterceptor(LockTemplate lockTemplate, LockKeyBuilder lockKeyBuilder,
                                           LockFailureStrategy lockFailureStrategy) {
        return new LockInterceptor(lockTemplate, lockKeyBuilder, lockFailureStrategy, properties);
    }

    /**
     * 分布式锁aop通知
     * @param lockInterceptor
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    public LockAnnotationAdvisor lockAnnotationAdvisor(LockInterceptor lockInterceptor) {
        return new LockAnnotationAdvisor(lockInterceptor, Ordered.HIGHEST_PRECEDENCE);
    }
}
